From a65fd81106a677e870d2f440aa3613deb546c828 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 29 Mar 2020 15:19:23 -0400 Subject: [PATCH] root: Reorganize focus handling Make :focus-widget a GtkWindow property and add vfuncs to the GtkRoot interface instead of the property. --- gtk/gtkdragicon.c | 8 ---- gtk/gtkroot.c | 40 ++++++++------------ gtk/gtkrootprivate.h | 13 +++---- gtk/gtkwindow.c | 88 +++++++++++++++++++++++++++++--------------- 4 files changed, 80 insertions(+), 69 deletions(-) diff --git a/gtk/gtkdragicon.c b/gtk/gtkdragicon.c index dc52dbcf54..bc13f75a93 100644 --- a/gtk/gtkdragicon.c +++ b/gtk/gtkdragicon.c @@ -317,10 +317,6 @@ gtk_drag_icon_get_property (GObject *object, g_value_set_object (value, self->child); break; - case LAST_ARG + GTK_ROOT_PROP_FOCUS_WIDGET: - g_value_set_object (value, NULL); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -341,9 +337,6 @@ gtk_drag_icon_set_property (GObject *object, gtk_drag_icon_set_child (self, g_value_get_object (value)); break; - case LAST_ARG + GTK_ROOT_PROP_FOCUS_WIDGET: - // do nothing - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -382,7 +375,6 @@ gtk_drag_icon_class_init (GtkDragIconClass *klass) G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, LAST_ARG, properties); - gtk_root_install_properties (object_class, LAST_ARG); gtk_widget_class_set_css_name (widget_class, "dnd"); } diff --git a/gtk/gtkroot.c b/gtk/gtkroot.c index 3e6a7b78b6..0252b85856 100644 --- a/gtk/gtkroot.c +++ b/gtk/gtkroot.c @@ -59,18 +59,25 @@ gtk_root_default_get_constraint_solver (GtkRoot *self) return NULL; } +static GtkWidget * +gtk_root_default_get_focus (GtkRoot *self) +{ + return NULL; +} + +static void +gtk_root_default_set_focus (GtkRoot *self, + GtkWidget *focus) +{ +} + static void gtk_root_default_init (GtkRootInterface *iface) { iface->get_display = gtk_root_default_get_display; iface->get_constraint_solver = gtk_root_default_get_constraint_solver; - - g_object_interface_install_property (iface, - g_param_spec_object ("focus-widget", - P_("Focus widget"), - P_("The focus widget"), - GTK_TYPE_WIDGET, - GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); + iface->get_focus = gtk_root_default_get_focus; + iface->set_focus = gtk_root_default_set_focus; } /** @@ -123,7 +130,7 @@ gtk_root_set_focus (GtkRoot *self, g_return_if_fail (GTK_IS_ROOT (self)); g_return_if_fail (focus == NULL || GTK_IS_WIDGET (focus)); - g_object_set (self, "focus-widget", focus, NULL); + GTK_ROOT_GET_IFACE (self)->set_focus (self, focus); } /** @@ -143,22 +150,7 @@ gtk_root_set_focus (GtkRoot *self, GtkWidget * gtk_root_get_focus (GtkRoot *self) { - GtkWidget *focus; - g_return_val_if_fail (GTK_IS_ROOT (self), NULL); - g_object_get (self, "focus-widget", &focus, NULL); - - if (focus) - g_object_unref (focus); - - return focus; -} - -guint -gtk_root_install_properties (GObjectClass *object_class, - guint first_prop) -{ - g_object_class_override_property (object_class, first_prop + GTK_ROOT_PROP_FOCUS_WIDGET, "focus-widget"); - return GTK_ROOT_NUM_PROPERTIES; + return GTK_ROOT_GET_IFACE (self)->get_focus (self); } diff --git a/gtk/gtkrootprivate.h b/gtk/gtkrootprivate.h index 41f1360673..57246127a5 100644 --- a/gtk/gtkrootprivate.h +++ b/gtk/gtkrootprivate.h @@ -21,17 +21,14 @@ struct _GtkRootInterface GdkDisplay * (* get_display) (GtkRoot *self); GtkConstraintSolver * (* get_constraint_solver) (GtkRoot *self); -}; -GtkConstraintSolver * gtk_root_get_constraint_solver (GtkRoot *self); + GtkWidget * (* get_focus) (GtkRoot *self); + void (* set_focus) (GtkRoot *self, + GtkWidget *focus); -typedef enum { - GTK_ROOT_PROP_FOCUS_WIDGET, - GTK_ROOT_NUM_PROPERTIES -} GtkRootProperties; +}; -guint gtk_root_install_properties (GObjectClass *object_class, - guint first_prop); +GtkConstraintSolver * gtk_root_get_constraint_solver (GtkRoot *self); G_END_DECLS diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 42135b8bb9..745946c8b2 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -288,6 +288,7 @@ enum { PROP_TRANSIENT_FOR, PROP_APPLICATION, PROP_DEFAULT_WIDGET, + PROP_FOCUS_WIDGET, /* Readonly properties */ PROP_IS_ACTIVE, @@ -941,8 +942,14 @@ gtk_window_class_init (GtkWindowClass *klass) GTK_TYPE_WIDGET, GTK_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY); + window_props[PROP_FOCUS_WIDGET] = + g_param_spec_object ("focus-widget", + P_("Focus widget"), + P_("The focus widget"), + GTK_TYPE_WIDGET, + GTK_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (gobject_class, LAST_ARG, window_props); - gtk_root_install_properties (gobject_class, LAST_ARG); /** * GtkWindow::activate-focus: @@ -1858,7 +1865,7 @@ gtk_window_set_property (GObject *object, case PROP_FOCUS_VISIBLE: gtk_window_set_focus_visible (window, g_value_get_boolean (value)); break; - case LAST_ARG + GTK_ROOT_PROP_FOCUS_WIDGET: + case PROP_FOCUS_WIDGET: gtk_window_set_focus (window, g_value_get_object (value)); break; default: @@ -1941,7 +1948,7 @@ gtk_window_get_property (GObject *object, case PROP_IS_MAXIMIZED: g_value_set_boolean (value, gtk_window_is_maximized (window)); break; - case LAST_ARG + GTK_ROOT_PROP_FOCUS_WIDGET: + case PROP_FOCUS_WIDGET: g_value_set_object (value, gtk_window_get_focus (window)); break; default: @@ -2028,6 +2035,52 @@ gtk_window_root_get_constraint_solver (GtkRoot *root) return priv->constraint_solver; } +static GtkWidget * +gtk_window_root_get_focus (GtkRoot *root) +{ + GtkWindow *self = GTK_WINDOW (root); + GtkWindowPrivate *priv = gtk_window_get_instance_private (self); + + return priv->focus_widget; +} + +static void synthesize_focus_change_events (GtkWindow *window, + GtkWidget *old_focus, + GtkWidget *new_focus); + +static void +gtk_window_root_set_focus (GtkRoot *root, + GtkWidget *focus) +{ + GtkWindow *self = GTK_WINDOW (root); + GtkWindowPrivate *priv = gtk_window_get_instance_private (self); + GtkWidget *old_focus = NULL; + + if (focus && !gtk_widget_is_sensitive (focus)) + return; + + if (focus == priv->focus_widget) + return; + + if (priv->focus_widget) + old_focus = g_object_ref (priv->focus_widget); + g_set_object (&priv->focus_widget, NULL); + + if (old_focus) + gtk_widget_set_has_focus (old_focus, FALSE); + + synthesize_focus_change_events (self, old_focus, focus); + + if (focus) + gtk_widget_set_has_focus (focus, TRUE); + + g_set_object (&priv->focus_widget, focus); + + g_clear_object (&old_focus); + + g_object_notify (G_OBJECT (self), "focus-widget"); +} + static void gtk_window_native_get_surface_transform (GtkNative *native, int *x, @@ -2054,6 +2107,8 @@ gtk_window_root_interface_init (GtkRootInterface *iface) { iface->get_display = gtk_window_root_get_display; iface->get_constraint_solver = gtk_window_root_get_constraint_solver; + iface->get_focus = gtk_window_root_get_focus; + iface->set_focus = gtk_window_root_set_focus; } static void @@ -5610,34 +5665,9 @@ void gtk_window_set_focus (GtkWindow *window, GtkWidget *focus) { - GtkWindowPrivate *priv = gtk_window_get_instance_private (window); - GtkWidget *old_focus = NULL; - g_return_if_fail (GTK_IS_WINDOW (window)); - if (focus && !gtk_widget_is_sensitive (focus)) - return; - - if (focus == priv->focus_widget) - return; - - if (priv->focus_widget) - old_focus = g_object_ref (priv->focus_widget); - g_set_object (&priv->focus_widget, NULL); - - if (old_focus) - gtk_widget_set_has_focus (old_focus, FALSE); - - synthesize_focus_change_events (window, old_focus, focus); - - if (focus) - gtk_widget_set_has_focus (focus, TRUE); - - g_set_object (&priv->focus_widget, focus); - - g_clear_object (&old_focus); - - g_object_notify (G_OBJECT (window), "focus-widget"); + gtk_root_set_focus (GTK_ROOT (window), focus); } static void -- 2.30.2